import { Request, Response, NextFunction } from 'express';
import { validationResult } from 'express-validator';

// 验证中间件
export const validateRequest = (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const errors = validationResult(req);
  
  if (!errors.isEmpty()) {
    const errorMessages = errors.array().map(error => ({
      field: error.type === 'field' ? error.path : 'unknown',
      message: error.msg,
      value: error.value
    }));

    return res.status(400).json({
      success: false,
      error: '请求参数验证失败',
      details: errorMessages
    });
  }

  next();
};

// 自定义验证规则
export const customValidators = {
  // 检查字符串长度范围
  isLengthRange: (min: number, max: number) => {
    return (value: string) => {
      if (!value) return true; // 空值由其他验证器处理
      return value.length >= min && value.length <= max;
    };
  },

  // 检查是否为有效的颜色值
  isValidColor: (value: string) => {
    if (!value) return true;
    return /^#[0-9A-F]{6}$/i.test(value);
  },

  // 检查是否为有效的URL
  isValidUrl: (value: string) => {
    if (!value) return true;
    try {
      new URL(value);
      return true;
    } catch {
      return false;
    }
  },

  // 检查是否为有效的日期
  isValidDate: (value: string) => {
    if (!value) return true;
    const date = new Date(value);
    return !isNaN(date.getTime());
  },

  // 检查是否为有效的文件大小（MB）
  isValidFileSize: (maxSizeMB: number) => {
    return (value: number) => {
      if (!value) return true;
      return value <= maxSizeMB * 1024 * 1024;
    };
  },

  // 检查是否为有效的文件类型
  isValidFileType: (allowedTypes: string[]) => {
    return (value: string) => {
      if (!value) return true;
      return allowedTypes.includes(value);
    };
  },

  // 检查是否为有效的排序字段
  isValidSortField: (allowedFields: string[]) => {
    return (value: string) => {
      if (!value) return true;
      return allowedFields.includes(value);
    };
  },

  // 检查是否为有效的排序顺序
  isValidSortOrder: (value: string) => {
    if (!value) return true;
    return ['asc', 'desc'].includes(value.toLowerCase());
  },

  // 检查是否为有效的状态值
  isValidStatus: (allowedStatuses: string[]) => {
    return (value: string) => {
      if (!value) return true;
      return allowedStatuses.includes(value);
    };
  },

  // 检查是否为有效的角色值
  isValidRole: (value: string) => {
    if (!value) return true;
    return ['ADMIN', 'EDITOR', 'VIEWER'].includes(value);
  },

  // 检查是否为有效的用户状态
  isValidUserStatus: (value: string) => {
    if (!value) return true;
    return ['ACTIVE', 'INACTIVE', 'BANNED'].includes(value);
  },

  // 检查是否为有效的知识库状态
  isValidKnowledgeBaseStatus: (value: string) => {
    if (!value) return true;
    return ['DRAFT', 'PUBLISHED', 'ARCHIVED'].includes(value);
  },

  // 检查是否为有效的评论状态
  isValidCommentStatus: (value: string) => {
    if (!value) return true;
    return ['PENDING', 'APPROVED', 'REJECTED'].includes(value);
  },

  // 检查是否为有效的分页参数
  isValidPagination: (req: Request) => {
    const page = parseInt(req.query.page as string) || 1;
    const limit = parseInt(req.query.limit as string) || 20;
    
    if (page < 1 || limit < 1 || limit > 100) {
      return false;
    }
    
    return true;
  },

  // 检查是否为有效的搜索参数
  isValidSearchParams: (req: Request) => {
    const { search, categoryId, tagIds, authorId, status } = req.query;
    
    // 至少需要一个搜索条件
    if (!search && !categoryId && !tagIds && !authorId && !status) {
      return false;
    }
    
    return true;
  },

  // 检查是否为有效的日期范围
  isValidDateRange: (req: Request) => {
    const { dateFrom, dateTo } = req.query;
    
    if (dateFrom && dateTo) {
      const from = new Date(dateFrom as string);
      const to = new Date(dateTo as string);
      
      if (isNaN(from.getTime()) || isNaN(to.getTime()) || from > to) {
        return false;
      }
    }
    
    return true;
  }
};

// 错误处理中间件
export const handleValidationError = (
  error: any,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  if (error.type === 'entity.parse.failed') {
    return res.status(400).json({
      success: false,
      error: '请求体格式错误',
      details: 'JSON格式不正确'
    });
  }

  if (error.type === 'entity.too.large') {
    return res.status(413).json({
      success: false,
      error: '请求体过大',
      details: '请求数据超过了允许的大小限制'
    });
  }

  next(error);
};

// 清理和转换中间件
export const sanitizeInput = (req: Request, res: Response, next: NextFunction) => {
  // 清理字符串字段
  if (req.body) {
    Object.keys(req.body).forEach(key => {
      if (typeof req.body[key] === 'string') {
        req.body[key] = req.body[key].trim();
      }
    });
  }

  // 清理查询参数
  if (req.query) {
    Object.keys(req.query).forEach(key => {
      if (typeof req.query[key] === 'string') {
        req.query[key] = (req.query[key] as string).trim();
      }
    });
  }

  next();
};

// 参数类型转换中间件
export const convertTypes = (req: Request, res: Response, next: NextFunction) => {
  // 转换查询参数类型
  if (req.query.page) {
    req.query.page = parseInt(req.query.page as string) || 1;
  }
  
  if (req.query.limit) {
    req.query.limit = parseInt(req.query.limit) || 20;
  }
  
  if (req.query.featured !== undefined) {
    req.query.featured = req.query.featured === 'true';
  }

  // 转换请求体类型
  if (req.body.page) {
    req.body.page = parseInt(req.body.page) || 1;
  }
  
  if (req.body.limit) {
    req.body.limit = parseInt(req.body.limit) || 20;
  }
  
  if (req.body.featured !== undefined) {
    req.body.featured = Boolean(req.body.featured);
  }

  next();
};
